using System.Linq;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using Wolfpack.Contrib.BuildAnalytics.Publishers;
using Wolfpack.Core;
using Wolfpack.Core.Interfaces.Entities;
using Wolfpack.Core.Notification;

namespace Wolfpack.Contrib.BuildAnalytics.Tfs.Parsers
{
    public class MSTestCoverageReportParser : BuildNotificationPublisherBase<MSTestCoverageReportParserConfig>
    {
        public MSTestCoverageReportParser(MSTestCoverageReportParserConfig config)
            : base(config, config.TargetHealthCheckName)
        {
        }

        protected override void Publish(NotificationEvent notification)
        {
            var serverUrl = notification.Properties[NotificationProperties.ServerUrl];
            var teamProject = notification.Properties[NotificationProperties.ProjectName];
            var buildUri = notification.Properties[NotificationProperties.BuildUri];
            var buildDefName = notification.Properties[NotificationProperties.ConfigurationName];

            var tfs = new TfsTeamProjectCollection(TfsTeamProjectCollection.GetFullyQualifiedUriForName(serverUrl));
            var tms = tfs.GetService<ITestManagementService>();
            var testManager = tms.GetTeamProject(teamProject);
            var coverageAnalysisManager = testManager.CoverageAnalysisManager;
            var queryBuildCoverage = coverageAnalysisManager.QueryBuildCoverage(buildUri, CoverageQueryFlags.Modules);

            var stats = queryBuildCoverage.SelectMany(x => x.Modules.Select(m => 
                            new
                            {
                                m.Name,
                                Coverage = (m.Statistics.BlocksCovered*100) / (m.Statistics.BlocksCovered + m.Statistics.BlocksNotCovered),
                                m.Statistics.BlocksCovered,
                                m.Statistics.BlocksNotCovered
                            }))
                            .Distinct()
                            .ToList();

            var totalCovered = stats.Sum(x => x.BlocksCovered);
            var totalNotCovered = stats.Sum(x => x.BlocksNotCovered);
            var coverage = (totalCovered*100)/(totalCovered + totalNotCovered);
            var message = string.Format("Coverage for {0}, {1} is {2}%", teamProject, buildDefName, coverage);
            Logger.Debug(message);

            // send notification...
            var result = (coverage < Config.NotificationThreshold.GetValueOrDefault(0));
            var coverageData = HealthCheckData.For(new PluginDescriptor { Name = FriendlyId }, message)
                .ResultIs(result)
                .ResultCountIs(coverage)
                .DisplayUnitIs("%");


            stats.ForEach(x => coverageData.AddProperty(x.Name, string.Format("{0}%", x.Coverage)));            

            var request = NotificationRequestBuilder.AlwaysPublish(coverageData).Build();
            var notification2 = NotificationHub.ConvertRequestToEvent(request);
            Messenger.Publish(notification2);
        }
    }
}